import netsvc
import operator
import time
import datetime
from osv import osv, fields
from osv.orm import intersect
import tools.sql
from tools import config
from tools.translate import _
from mx import DateTime
import mx.DateTime
from mx.DateTime import RelativeDateTime, now, DateTime, localtime
from datetime import date
from tools.translate import _


class kdvn_request_of_payment(osv.osv):
    _name = 'kdvn.request.of.payment'
    #_inherit = 'account.invoice'
    _description="KDVN Request of Payment"
    _rec_name="description"
    _order = "rop_date desc"
    _order = "paymentno desc"
 
    def write(self, cr, uid, ids, vals, context=None):
        self.pool.get('ir.rule').domain_get.clear_cache(cr.dbname)
        
        if context:
            if len(ids)>0 and 'date_of_submit_to_accounting' in context:
                cr.execute("Update kdvn_request_of_payment set date_of_submit_to_accounting='%s' where id in (%s) and date_of_submit_to_accounting is null" % (time.strftime('%Y-%m-%d'),",".join(map(str,ids))) )
        osv.osv.write(self, cr, uid, ids,vals,context=context)
#         tax_amount = vals.get('tax_amount', 0)
#         tax_per = vals.get('tax_per', 0)
#         amount = vals.get('amount', 0)
#         advanced_amount = vals.get('advanced_amount', 0)
#         retention_amount = vals.get('retention_amount', 0)
#         cr.execute("Select id from kdvn_request_of_payment where id in (%) and coalesce(amount,0)=0 and  coalesce(advanced_amount,0)=0 and coalesce(retention_amount,0)=0")
#         
#         list_update=[]
#         
#         for id in cr.fetchall():
#             list_update.append([id[0]])
#             ids.pop(id[0]) 
#         #
#         if len(list_update)==1 and (amount==0) and advanced_amount==0 and retention_amount==0 and 'state' not in vals:
#             cr.execute("Select subtotal,amount_tax,tax_percent from kderp_supplier_vat_invoice ksvi left join kderp_rop_supplier_vat_invoice krsvi on id = kderp_supplier_vat_invoice_id  where rop_id = %s" % ids[0])
#             
#             res = cr.fetchall()
#             if res:
#                 amount =res[0][0]
#                 #if not tax_amount:
#                 tax_amount = res [0][1]
#                 tax_per=res[0][2]
#                 vals['amount'] = amount
#                 vals['tax_per'] = tax_per
#                 vals['tax_amount'] = tax_amount
#             osv.osv.write(self, cr, uid, list_update,vals,context=context)
#         else:        
        return True
    
    def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
        if not args:
            args = []
        if not context:
            context = {}
        args = args[:]
        if context:
            if 'from_payment' in context.keys():
                args.append(('state','=','completed'))
        ids = []
        if name:
            ids = self.search(cr, user, [('paymentno', '=', name)]+args, limit=limit)
            if not ids:
                ids = self.search(cr, user, [('paymentno', 'ilike', name)]+ args, limit=limit)
            if not ids:
                ids = self.search(cr, user, [('description', 'ilike', name)]+ args, limit=limit)
            if not ids:
                ids = self.search(cr, user, [('order_id', 'ilike', name)]+ args, limit=limit)
        else:
            try:
                ids = self.search(cr, user, args, context=context, limit=limit)
            except:
                if 'from_payment' in context.keys():
                    ids = self.search(cr, user, [('state','=','completed')], context=context, limit=limit)
                else:
                    ids = self.search(cr, user, context=context, limit=limit)
        return self.name_get(cr, user, ids, context=context) 

    def fields_get(self, cr, uid, fields=None, context=None):
        res = super(kdvn_request_of_payment, self).fields_get(cr, uid, fields, context)
        new_field={'search_in_line_vatinvoice':
                                        {'widget':u'char',
                                         'type':u'char',
                                         'name':u'search_in_line_vatinvoice',
                                         'select': u'1',
                                         'string':u'Invoice No.',
                                         'invisible':True,
                                         'visible':False,
                                         'size':128,
                                         'sql':"(Select DISTINCT ROP_ID from kderp_rop_supplier_vat_invoice kprir FULL join kderp_supplier_vat_invoice kpri on kderp_supplier_vat_invoice_id=kpri.id WHERE COALESCE(ROP_ID,0)>0 and kpri.name ilike chr(37) || '%s' || chr(37))"}}
        res.update(new_field)
        return res
    
    def name_get(self, cr, uid, ids, context={}):
        if not len(ids):
            return []
        res = []
        code_only=False
        if context:
            if 'code_only' in context:
                code_only=True
        if code_only:
            for record in self.read(cr, uid, ids, ['paymentno'], context):
                name = record['paymentno']
                res.append((record['id'],name))
        else:
            for record in self.read(cr, uid, ids, ['paymentno','description'], context):
                #raise osv.except_osv("E",record)
                name = ""                
                if type(record['description']) in (type('str'),type(u'str')) and type(record['paymentno']) in (type('str'),type(u'str')):                    
                    if len(record['paymentno'].strip())>0 and len(record['description'].strip())>0:
                        name = record['paymentno'] + " - " +  record['description']
                    elif len(record['description'].strip())>0:
                        name = record['description']
                    elif len(record['paymentno'].strip())>0:
                        name = record['paymentno']
                elif type(record['description'])in (type('str'),type(u'str')):
                    if len(record['description'].strip())>0:
                        name = record['description']
                    else:
                        name = 'Not Available'        
                elif type(record['paymentno']) in (type('str'),type(u'str')):
                    if len(record['paymentno'].strip())>0:
                        name = record['paymentno']
                    else:
                        name = 'Not Available'
                else:
                    name = 'Not Available'
                res.append((record['id'],name ))
        return res

    def unlink(self, cr, uid, ids, context=None):
        if ids:
            payment_id = ",".join(map(str,ids))
            for rop in self.read(cr,uid,ids,['state']):
                if rop['state'] not in ('draft','submitting'):
                    raise osv.except_osv("KDVN Warning !","Can't delete payment please check status")
        unlink_ids = ids
        return super(kdvn_request_of_payment, self).unlink(cr, uid, unlink_ids, context=context)
        
    def _onchange_due_date(self, cr, uid, ids,rop_date_str):        
        if rop_date_str:
            from datetime import datetime as ldatetime
            rop_date = ldatetime.strptime(rop_date_str, '%Y-%m-%d')           
            m = rop_date.month
            d = rop_date.day
            y = rop_date.year
            if m==12 :
                if (d>25):
                    m = 2
                    y = y + 1
                    d = 10                                
                elif (d<11):
                    m = 1
                    y = y + 1
                    d = 10
                else:
                    m = 1
                    y = y + 1
                    d = 25                            
            elif m==11:
                if (d>25):
                    m = 1
                    y = y + 1
                    d = 10
                elif (d<11):
                    m= m +1
                    d = 10
                else:
                    m= m +1
                    d= 25
            else:
                if (d>25):
                    m = m + 2
                    d = 10
                elif (d<11):
                    m = m + 1
                    d = 10
                else:
                    m = m + 1
                    d = 25 
            due_date = datetime.date(y, m, d).strftime("%Y-%m-%d")
            #raise osv.except_osv("E",due_date)
        else:
            due_date = False
        #raise osv.except_osv("E",{'value':{'due_date':due_date}})    
        return due_date
        
    def _onchange_date(self, cr, uid, ids,oldnumber,po_id=False,due_date=False,project_id=False):
        if due_date:
            due_date = self.pool.get('kdvn.common.function').check_date(due_date)
            due_date = self._onchange_due_date(cr,uid,ids,due_date)

        new_number=self._invoice_no(cr,uid,{'po_id':po_id,'oldnumber':oldnumber,'project_id':project_id})

        val={'paymentno':new_number,'due_date':due_date}        
        return {'value':val}

    def onchange_po_id(self, cr, uid, ids, po_id,
            paymentno=False):
        partner_id = False
        project_id=False
        currency_id=False
        
        opt = [('uid', str(uid))]
        if po_id:
            res_po=self.pool.get('purchase.order').search(cr,uid,[('id','=',po_id)])
            res_partner_id=self.pool.get('purchase.order').read(cr, uid, res_po, ['partner_id','project_id','currency_id'])
            partner_id=res_partner_id[0]['partner_id'][0]
            project_id=res_partner_id[0]['project_id'][0]
            if res_partner_id[0]['currency_id']:
                currency_id=res_partner_id[0]['currency_id'][0]
        new_number=self._invoice_no(cr,uid,{'po_id':po_id,'oldnumber':paymentno,'project_id':project_id})
        result = {'value': {'supplier_id':partner_id,
            'project_id':project_id,'currency_id':currency_id,'paymentno':new_number
            }
        }
        return result
    
    def _invoice_no(self, cr, uid, context={}):
        typeoforder='E'
        oldnumber=""
        project_id = False
        if 'project_id' in context:
            project_id = context['project_id']
        if project_id:       
            cr.execute("""Select
                            kp.project_type
                        from
                            kdvn_project kp
                        where kp.id=%s""" % project_id)
            res_tmp = cr.fetchone()
            if res_tmp:                 
                typeoforder = res_tmp[0]
        if 'oldnumber' in context:
            if context['oldnumber']:
                oldnumber = context['oldnumber']
                
        if typeoforder=='E' and oldnumber.upper().find('INE')>=0:
            return oldnumber
        elif typeoforder=='M' and oldnumber.upper().find('INM')>=0:
            return oldnumber
        else:
            if typeoforder=='E':
                filter_condition = "ilike '%electrical'"
            else:
                filter_condition = "not ilike '%electrical'"
            cr.execute("Select newcode from vwnewcode_rop where name " + filter_condition)
            res=cr.fetchone()[0]            
        return res

    def _seri_no(self, cr, uid, ids, name, args, context={}):
        res = {}
        if ids:
            for id in ids:
                res[id]=0
            payment_ids = ",".join(map(str,ids))
            cr.execute("Select \
                            id,\
                            substring(paymentno from 6 for 4)\
                        from \
                            kdvn_request_of_payment\
                        where\
                            length(paymentno)>4 and id in (%s)" % payment_ids)
            payment_list = cr.fetchall()
            for p_id,s_no in payment_list:
                if s_no.isdigit():
                    res[p_id] = int(s_no)
                else:
                    res[p_id] = 0
        return res
    
    def _get_value_year_selection(self,cr,uid,context={}): #get value only
        res = []        
        cr.execute("Select \
                        distinct\
                        substring(paymentno from 1 for 4)\
                    from \
                        kdvn_request_of_payment\
                    where\
                        length(paymentno)>4")
        payment_list = cr.fetchall()
        
        for s_prefixyear in payment_list:
            if type(s_prefixyear)!=type(" "):
                s_prefixyear_1=s_prefixyear[0]
            res.append((s_prefixyear_1,s_prefixyear_1))
        #raise osv.except_osv("E",res)
        return res
        
    def _seri_prefixyear(self, cr, uid, ids, name, args, context={}):
        res = {}
        if ids:
            for id in ids:
                res[id]=False
            payment_ids = ",".join(map(str,ids))
            cr.execute("Select \
                        id,\
                        substring(paymentno from 1  for 4)\
                    from \
                        kdvn_request_of_payment\
                    where\
                        length(paymentno)>4 and id in (%s)" % payment_ids)
            payment_list = cr.fetchall()
        #raise osv.except_osv("E",payment_list)
            for rop_id,s_prefixyear in payment_list:
                #if type(s_prefixyear)!=type(" "):
                 #   s_prefixyear=s_prefixyear[0]
                res[rop_id]=s_prefixyear
        #raise osv.except_osv("E",res)
        return res
       
    def _get_vat_invoices_nos(self, cr, uid, ids, name, args, context={}):
        res = {}
        if ids:
            rop_ids = ",".join(map(str,ids))
            cr.execute("Select\
                            krop.id,sum(kpri.name || ';')\
                        from\
                            kdvn_request_of_payment krop\
                        left join\
                            kdvn_request_of_payment_kdvn_purchase_red_invoice_rel krv on krop.id = rop_id\
                        left join\
                            kdvn_purchase_red_invoice kpri on kdvn_purchase_red_invoice_id = kpri.id\
                        where\
                            krop.id in (%s)\
                        group by \
                            krop.id" % (rop_ids))
            for id,nos in cr.fetchall():
                res[id]=nos
        return res
    
    def _get_subtotal_amount_in_compnay_currency(self, cr, uid, ids, name, args, context={}):
        res = {}
        if ids:
            rop_ids = ",".join(map(str,ids))
            cr.execute("""Select
                            krop.id,
                            coalesce(fncompute(currency_id,get_default_currency(),rop_date,'tax_office'),0)*
                            (coalesce(amount,0)+coalesce(advanced_amount,0)+coalesce(retention_amount,0)) 
                        from
                            kdvn_request_of_payment krop
                        where
                            krop.id in (%s)
                        group by 
                            krop.id""" % (rop_ids))
            for id,nos in cr.fetchall():
                res[id]=nos
        return res
    
    def _kdvn_amount_all(self, cr, uid, ids, name, args, context={}):
        res = {}
        for x in self.browse(cr,uid,ids, context=context):
            res[x.id] =x.amount + x.tax_amount + x.advanced_amount + x.retention_amount
        for id in ids:
            res[id] = res.get(id, 0.0)
        return res
        
    def action_unlock(self, cr, uid, ids, *args):
        if ids:
            rop_ids = ",".join(map(str,ids))
            cr.execute("Select \
                            manager_id as user_id\
                        from \
                            hr_department hd\
                        where \
                            id in\
                            (Select\
                                distinct\
                                department_id\
                            from \
                                hr_department_user_rel hdur\
                            where \
                                user_id in\
                                    (Select\
                                        create_uid\
                                    from\
                                        kdvn_request_of_payment krop\
                                    where \
                                        id in (%s)))\
                        union\
                            Select\
                                create_uid as user_id\
                            from\
                                kdvn_request_of_payment krop\
                            where \
                                id in (%s)" % (rop_ids,rop_ids))
            list_user_right=[]
            for user in cr.fetchall():
                if type(user)!=type(1):
                    list_user_right.append(user[0])
                else:
                    list_user_right.append(user)
            if uid in list_user_right:                
                self.write(cr, uid, ids, {'locked':False})
            else:
                raise osv.except_osv("KDVN Warning","You can't lock this record, only user created this record or his/her manager can !")
        return True
        
    def action_super_lock(self, cr, uid, ids, *args):
        if ids:
            self.write(cr,uid,ids,{'super_unlock':False})
        return True
    
    def action_super_unlock(self, cr, uid, ids, *args):
        if ids:
            self.write(cr,uid,ids,{'super_unlock':True})
        return True
    
    def action_lock(self, cr, uid, ids, *args):
        if ids:
            rop_ids = ",".join(map(str,ids))
            cr.execute("Select \
                            manager_id as user_id\
                        from \
                            hr_department hd\
                        where \
                            id in\
                            (Select\
                                distinct\
                                department_id\
                            from \
                                hr_department_user_rel hdur\
                            where \
                                user_id in\
                                    (Select\
                                        create_uid\
                                    from\
                                        kdvn_request_of_payment krop\
                                    where \
                                        id in (%s)))\
                        union\
                            Select\
                                create_uid as user_id\
                            from\
                                kdvn_request_of_payment krop\
                            where \
                                id in (%s)" % (rop_ids,rop_ids))
            list_user_right=[]
            for user in cr.fetchall():
                if type(user)!=type(1):
                    list_user_right.append(user[0])
                else:
                    list_user_right.append(user)
            if uid in list_user_right:                
                self.write(cr, uid, ids, {'locked':True})
            else:
                raise osv.except_osv("KDVN Warning","You can't lock this record, only user created this record or manager can lock !")
        return True
    
    def action_cancel(self, cr, uid, ids, *args):
        self.write(cr, uid, ids, {'state':'cancel'})
        for rop_id in ids:
            try:                       
                wf_service.trg_delete(uid, 'kdvn.request.of.payment',rop_id, cr)
            except:
                b = True
        return True
    
    def action_cancel_paid(self, cr, uid, ids, *args):
        self.write(cr, uid, ids, {'state':'cancel'})
        return True
    
    def action_cancel_draft(self, cr, uid, ids, *args):
        self.write(cr, uid, ids, {'state':'draft'})
        wf_service = netsvc.LocalService("workflow")
        for inv_id in ids:
            wf_service.trg_create(uid, 'kdvn.request.of.payment', inv_id, cr)
        return True
    
    #Draft - Pr. Checking
    def action_rop_draft_to_waiting_for_payment(self,cr,uid,ids,*args):
        if not len(ids):
            return False        
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_draft_to_waiting_payment', cr)
#        if args:
#            ctx=args[0]
#            if ctx:
#                if 'date' in ctx:
#                    dt = ctx['date']
#                    self.write(cr, uid, ids, {'pro_to_acc' :dt})
        return True
    
    #Pr. Checking - Draft
    def action_rop_pr_checking_draft(self,cr,uid,ids,*args):
        if not len(ids):
            return False        
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_pr_checking_to_draft', cr)
        return True
    
    #Pr. Checking - BC Checking
    def action_rop_pr_checking_bc_checking(self,cr,uid,ids,*args):
        if not len(ids):
            return False        
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_pr_checking_to_bc_checking', cr)
        if args:
            ctx=args[0]
            if ctx:
                if 'date' in ctx:
                    dt = ctx['date']
                    self.write(cr, uid, ids, {'to_bc_date_first' :dt})
        return True
    
    #BC Checking - BC Passed
    def action_rop_bc_confirm(self,cr,uid,ids,*args):
        if not len(ids):
            return False        
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_bc_confirm', cr)
        if args:
            ctx=args[0]
            if ctx:
                if 'date' in ctx:
                    dt = ctx['date']
                    self.write(cr, uid, ids, {'bc_checked_date' :dt})   
        return True
    
    #BC Passed - PM Checking
    def action_rop_send_to_pm(self,cr,uid,ids,*args):
        if not len(ids):
            return False        
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_pro_to_site', cr)
        if args:
            ctx=args[0]
            if ctx:
                if 'date' in ctx:
                    dt = ctx['date']
                    self.write(cr, uid, ids, {'to_site_date' :dt})   
        return True
    
    #PM Checking - BOD Checking
    def wkf_action_pmchecking_bodchecking(self,cr,uid,ids,*args): #For Workflow
        dt = None
        if args:
            ctx=args[0]
            if ctx:
                if 'date' in ctx:
                    dt = ctx['date']
        #for id in ids:
        self.write(cr, uid, ids, {'state' : 'waiting_bod', 'to_bc_date_second' : dt})
        return True
    
    def action_rop_pm_confirm(self,cr,uid,ids,*args): #For Process
        if not len(ids):
            return False
                
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_pm_confirm', cr)
        if args:
            ctx=args[0]
            if ctx:
                if 'date' in ctx:
                    dt = ctx['date']
                    self.write(cr, uid, ids, {'to_bc_date_second' :dt})
        return True
    
    
    #Draft -> Waiting BOD - Expense
    def action_rop_draft_bod_checking(self,cr,uid,ids,*args):
        if not len(ids):
            return False        
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_draft_to_pr_checking', cr)
        return True
    
    def action_rop_bod_confirm(self,cr,uid,ids,*args): # For Process
        if not len(ids):
            return False        
        wf_service = netsvc.LocalService("workflow")
        for pr_id in ids:
            wf_service.trg_validate(uid, 'kdvn.request.of.payment', pr_id,'btn_bod_confirm', cr)
        if args:
            ctx=args[0]
            if ctx:
                if 'date' in ctx:
                    dt = ctx['date']
                    self.write(cr, uid, ids, {'bc_to_accounting_date' :dt})
        return True    
                
    def action_payment_done(self, cr, uid, ids, *args): # For Work-flow
        self.write(cr,uid,ids,{'state':'completed'},{'date_of_submit_to_accounting':True})
        cr.commit()
        list_done=[]
        for rop in self.browse(cr, uid, ids):
            if rop.kdvn_payment_ids:
                list_done.append(rop.id)
        self.write(cr,uid,list_done,{'state':'paid'})
        return True

    def copy(self, cr, uid, id, default=None, context=None):
        if default is None:
            default = {}
        default = default.copy()
        default.update({'state':'draft', 'paymentno':"",'rop_date':False,'due_date':False,'date_of_submit_to_accounting':False,'kdvn_red_invoice_ids':None,'kdvn_payment_ids':None})
        #raise osv.except_osv("E",default)
        new_id = super(kdvn_request_of_payment, self).copy(cr, uid, id, default, context)
        self.write(cr,uid,[new_id],{'state':'draft'}) 
        return new_id

    def _get_typedocument(self,cr,uid,ids, name, args,context):
        res={}
        if ids:
            rop_ids = ",".join(map(str,ids))
            cr.execute("Select \
                            krop.id,\
                            pt.code \
                        from \
                            kdvn_request_of_payment krop \
                        left join \
                            purchase_order po on krop.order_id=po.id \
                        left join\
                            purchase_typeoforder pt on po.typeoforder=pt.id\
                        where krop.id in (%s)" % rop_ids)
            for rop_id,code in cr.fetchall():
                res[rop_id] = code
        return res
    
    def _exrate(self, cr, uid, ids, name, arg, context={}):
        res = {}
        if ids:
            cr.execute("Select id,\
                                fncompute(currency_id,get_default_currency(),rop_date,'tax_office')\
                        from kdvn_request_of_payment where id in (%s) " % ",".join(map(str, ids)))
        for rop_id, rate in cr.fetchall():
            res[rop_id] = rate
        return res
    
    def _get_payment_link_id(self, cr, uid, ids, name, arg, context={}):
        res = {}
        for id in ids:
            res[id] = id
        return res
    
    def _get_project_manger(self, cr, uid, ids, name, arg, context={}):
        res={}
        for rop in self.browse(cr,uid,ids):
            if rop.order_id.project_manager_id:
                res[rop.id] = rop.order_id.project_manager_id.name
            else:
                res[rop.id] = False 
        return res
    
    def _get_order(self, cr, uid, ids, context={}):
        result = {}
        for po in self.pool.get('purchase.order').browse(cr, uid, ids, context=context):
            for rop in po.rop_ids:
                result[rop.id] = True
        return result.keys()
    
    def _get_user(self, cr, uid, ids, context={}):
        result = {}
        if ids:
            ru_ids = ','.join(map(str,ids))
            cr.execute("""Select 
                                krop.id
                            from 
                                kdvn_request_of_payment krop left join purchase_order po on order_id = po.id left join res_users ru on po.project_manager_id = ru.id
                            where ru.id in (%s)""" % ru_ids)
            for id in cr.fetchall():
                result[id[0]] = True
        return result.keys()
        
    _columns={
              'exrate':fields.function(_exrate,type='float',method=True,string='Ex.Rate'),
              'user_create_id':fields.many2one("res.users","Create User"),
              #'locked':fields.boolean("Locked"),
              'super_unlock':fields.boolean('Super Unlock'),
              
              'number':fields.function(_seri_no,type='integer',method=True,string='No.',
                                       store={'kdvn.request.of.payment': (lambda self, cr, uid, ids, c={}: ids, ['paymentno'], 10)}),
                                                 
              'year':fields.function(_seri_prefixyear,string='Year',size=8,method=True,type='selection',selection=_get_value_year_selection,
                                     store={'kdvn.request.of.payment': (lambda self, cr, uid, ids, c={}: ids, ['paymentno'], 10)}),
              
              'project_manager_id':fields.function(_get_project_manger,type='char',size=64,method=True,string='P.M',select=1,
                                                   store={
                                                          'kdvn.request.of.payment': (lambda self, cr, uid, ids, c={}: ids, ['order_id'], 10),
                                                          'purchase.order':(_get_order,['project_manager_id'], 10),
                                                          'res.users':(_get_user,['name'],10)}),
              
              'user_applicant_id':fields.many2one('res.users','Applicant User',readonly=True,states={'draft':[('readonly',False)]}),
              'by_cash':fields.boolean('By Cash',readonly=True,states={'draft':[('readonly',False)]}),
              
              #'line_change':fields.boolean('Line Update'),

              'paymentno':fields.char('R.O.P. No.',size=25,readonly=True,states={'draft':[('readonly',False)]}),
              'description':fields.text('Description',readonly=True,states={'draft':[('readonly',False)]}),
              
              'rop_date':fields.date('R.O.P. Date',readonly=True,states={'draft':[('readonly',False)]}),
              'date_of_submit_to_accounting':fields.date('To Acc. Date',readonly=True,states={'draft':[('readonly',False)]}),
              'due_date':fields.date('Due Date',readonly=True,states={'draft':[('readonly',False)]}),
              
              'order_id':fields.many2one('purchase.order','PO',required=True,readonly=True,states={'draft':[('readonly',False)]}),
              'payment_link_id':fields.function(_get_payment_link_id,type='many2one',relation='kdvn.request.of.payment',method=True,string='Payment'),
                      
              'project_id':fields.many2one('kdvn.project','Project',readonly=True,states={'draft':[('readonly',False)]}),
              'supplier_id':fields.many2one('res.partner','Supplier',domain=[('supplier', '=',True)],readonly=True,states={'draft':[('readonly',False)]}),
              'currency_id':fields.many2one('kderp.currency','Currency',required=True,readonly=True,states={'draft':[('readonly',False)]}),
              'tax_per':fields.float("VAT (%)",readonly=True,states={'draft':[('readonly',False)]}),#[(0,'0'),(5,'5'),(10,'10')],
              'amount':fields.float('Amount',readonly=True,states={'draft':[('readonly',False)]}),
              'advanced_amount':fields.float('Advanced',readonly=True,states={'draft':[('readonly',False)]}),
              'retention_amount':fields.float('Retention',readonly=True,states={'draft':[('readonly',False)]}),
              'tax_amount':fields.float('Tax Amount',readonly=True,states={'draft':[('readonly',False)]}),
              'total':fields.function(_kdvn_amount_all,string='Total',method=True,type='float',digits=(16,2),
                                      store={'kdvn.request.of.payment': (lambda self, cr, uid, ids, c={}: ids, ['amount',
                                                                                                                'advanced_amount',
                                                                                                                'retention_amount',
                                                                                                                'tax_amount'],10)}),
              
              #'detail_ids':fields.one2many('kderp.request.of.payment.detail','rop_id','Expense Detail',readonly=True,states={'draft':[('readonly',False)]},ondelete='cascade'),
              
              'kderp_vat_invoice_ids':fields.many2many('kderp.supplier.vat.invoice','kderp_rop_supplier_vat_invoice', 'rop_id', 'kderp_supplier_vat_invoice_id', 'VAT Invoices',readonly=True,states={'draft':[('readonly',False)]}),
              'kdvn_payment_ids': fields.one2many('kdvn.payment','payment_id','Payment Money',readonly=True,states={'completed':[('readonly',False)]}),
              #'name':fields.char("a",size=2),
              'vat_invoices_nos':fields.function(_get_vat_invoices_nos,type='char',size=256,method=True,string='VAT Invoices'),
              'amount_in_company_curr':fields.function(_get_subtotal_amount_in_compnay_currency,type='float',method=True,string='Amt. in Company Curr.'),
              'state': fields.selection([
                                        ('draft','Process'),
                                        ('completed','Waiting for Payment'), #BOD approved->Completed
                                        ('paid','Paid'),
                                        ('cancel','Rejected')],'State', select=True, readonly=True),
              }

    _sql_constraints = [
        ('payment_no_can_not_duplicate', 'CHECK (fn_check_duplicate_paymentno(id,paymentno))',  'KDVN Error: The payment number must be unique !')]
    
    _defaults = {  
                #'paymentno':"",
                'user_create_id':lambda obj,cr,uid,context: uid, 
               # 'office_code':lambda *x: 'H',
                'state': lambda *a: 'draft',
               # 'locked': lambda *a: False,
                'super_unlock':lambda *a:False
        }
          
    def _onchange_amount_tax(self, cr, uid, ids, per,amount,adv,retention,kdvn_amount_tax=False):
        if kdvn_amount_tax:
            amount_tax=kdvn_amount_tax            
        else:
            amount_tax=int(per)*amount/100.0
        amount_total=amount_tax+amount + adv + retention
        if ids:
            cr.execute("Update kdvn_request_of_payment set line_change=False where id=%s" % ids[0])
        val={'amount':amount,'total':amount_total,'tax_amount':amount_tax}
        result={'value':val}
        return result
    
    def init(self,cr):
        cr.execute("""Create or replace view vwnewcode_rop as
                        Select 
                            name,
                            prefix || 
                            to_char(current_date,suffix) 
                            ||
                            lpad((coalesce(max(substring(paymentno from (prefix || suffix).length+1 for padding)::int),0)+1)::text,padding,'0') as newcode
                        from
                            (Select 
                                paymentno,
                                ir.name,
                                prefix,
                                suffix,
                                padding
                            from 
                                kdvn_request_of_payment krop
                            right join
                                ir_sequence ir on paymentno like prefix || to_char(current_date,suffix) || lpad('_',padding,'_')
                            where code='kderp_supplier_payment_code' and active=True) vw group by prefix,padding,name,suffix""")
kdvn_request_of_payment()

class kdvn_payment(osv.osv):
    _description="KDVN Payment to Supplier"
    _name="kdvn.payment"
    
    def _onchange_payment_id(self, cr, uid, ids,payment_id):
        result = {}
        if payment_id:
            rop_obj = self.pool.get('kdvn.request.of.payment')
            currency_id = False
            total = 0.0
            for rop in rop_obj.browse(cr,uid,[payment_id]):
                if rop.currency_id:
                    currency_id = rop.currency_id.id
                total = rop.total
            result={'amount':total,
                    'currency_id':currency_id,
                    'payment_currency_id':currency_id,
                    'actual_amount':total,
                    'rate':1.0
                    }
        return {'value':result}
    
    def _onchange_amount(self, cr, uid, ids,amount,amount_default,rate=0):
        if rate>0:
          val={'actual_amount':amount*rate}
          return {'value':val}  
        elif amount==0:
            rate=0.0
        else:
            rate=amount_default/amount
        val={'rate':rate}
        return {'value':val}

    def _onchange_currency(self, cr, uid, ids,from_curr,to_curr,date,amount,actual_amount):
        #raise osv.except_osv("E","%s-%s" %(from_curr,to_curr))
        if not to_curr:
            val={'rate':1,'actual_amount':amount,'payment_currency_id':False}
        elif from_curr==to_curr:
            val={'rate':1,'actual_amount':amount}
        elif not date:
            val={'rate':0}
        else:
            date = self.pool.get('kdvn.common.function').check_date(date)
            rate=self.pool.get('kdvn.purchase.currency').compute(cr,uid,from_curr,to_curr,1,True,{'date':date})
            val={'rate':rate,'actual_amount':amount*rate}
        return {'value':val}
    
    def _get_currency(self,cr,uid,ids,name,arg,context={}):
        res = {}
        if ids:
            #acc_set = ",".join(map(str, ids))
            #cr.execute("Select kp.id,currency_id from kdvn_request_of_payment krop left join \
             #               kdvn_payment kp on krop.id=payment_id where kp.id in (%s) " % acc_set)
            for rop in self.browse(cr,uid,ids):
                if rop.payment_id.currency_id:
                    res[rop.id] = rop.payment_id.currency_id.id
                else:
                    res[rop.id] = False
#            for obj_id in ids:
#                res.setdefault(obj_id, 0)
            for id in ids:
                res[id] = res.get(id,False)
        return res
    
    def _new_payment(self, cr, uid, context={}):
        this_time=0
        if context:
            if 'payment_amount' in context:
                this_time=context['payment_amount']
        return this_time
    
    def _get_default_currency(self, cr, uid, context={}):
        res =False
        if context:
            if 'currency' in context:
                #invoice_curr_list=self.pool.get('kdvn.request.of.payment').read(cr,uid,[context['payment_id']],['currency_id'])[0]['currency_id']
                #if invoice_curr_list:
                 #   res=invoice_curr_list[0]
                res = context['currency']
        return res
    
    def _rate(self,cr,uid,ids,name,arg,context={}):
        res={}
        for kr in self.browse(cr,uid,ids):
            if kr.amount==0:
                res[kr.id]=0
            else:
                res[kr.id]=kr.actual_amount/kr.amount
        for id in ids:
            res[id]=res.get(id,0)
        return res
        
    def create(self, cr, uid, vals, context=None):
        payment_ids=[]
        if type(vals)==(type([])):
            for new_payment in vals:
                payment_ids.append(new_payment['payment_id'])
        else:
            payment_ids = [vals['payment_id']]
        new_ids = osv.osv.create(self, cr, uid,vals,context=context)
        cr.commit()
        check_updated = False
        p_order_ids = []
        if type(new_ids)<>type([]):
            new_ids = [new_ids]
        for paid_obj in self.browse(cr,uid,new_ids):
             p_order_ids.append(paid_obj.payment_id.order_id.id)
        if context:
            if '__last_update' in context:
                check_updated = True
                cr.execute("""Update kdvn_request_of_payment set state='paid',write_uid=%d,write_date='%s' where id in (%s)""" % (uid,time.strftime('%Y-%m-%d'),",".join(map(str,payment_ids))))
                #self.pool.get('purchase.order')._check_and_make_po_done(cr,uid,p_order_ids)
        if not check_updated:        
            self.pool.get('kdvn.request.of.payment').write(cr,uid,payment_ids,{'state':'paid'},context=context)
            #self.pool.get('purchase.order')._check_and_make_po_done(cr,uid,p_order_ids)
        return new_ids
        #return super(kdvn_payment, self).create(cr, uid, vals, context=context)
    
    def import_data(self, cr, uid, fields, datas, mode='init', current_module='', noupdate=False, context=None, filename=None):
        try:
            payment_id_pos = fields.index('payment_id')
        except:
            payment_id_pos = -1
        payment_no_list =[]
        if payment_id_pos>=0:
            for lst in datas:
                payment_no_list.append(lst[payment_id_pos])
            payment_nos =str(payment_no_list).replace("[","(").replace("]",")") #",".join(map(str,payment_no_list))
            #raise osv.except_osv("KDVN Error",payment_nos)
            cr.execute("Select paymentno from kdvn_request_of_payment krop where paymentno in %s and state!='completed'" % (payment_nos))
            #raise osv.except_osv("KDVN Error",payment_nos)
            res = cr.fetchall()
            if res:
                list =[]
                for pn in res:
                    list.append(str(pn[0]))
                raise osv.except_osv("KDVN Error","State of payment must be BOD Approved !\n%s" % str(list))
                
        return super(kdvn_payment, self).import_data(cr, uid, fields, datas,mode, current_module, noupdate, context, filename)
    _rec_name='payment_id'
    _columns={
              'payment_id':fields.many2one('kdvn.request.of.payment','Payment ID',ondelete='cascade',required=True,context={'from_payment':True}),#,domain=[('state','=','completed')]
              'date':fields.date('Date',required=True),
              'currency_id':fields.function(_get_currency,method=True,type="many2one",relation="kderp.currency",string="Currency"),
              'amount':fields.float('Amount'),
              'payment_currency_id':fields.many2one("kderp.currency",'Pay. Cur.',required=True,context={'typeofrate':'tax_office'}),
              'actual_amount':fields.float('Payment Amount'),
              'rate':fields.float('@')
              #'rate':fields.float('Ex. Rate')
              }
    #_sql_constraints = [
     #   ('request_of_payment_cannot_duplicate', 'unique (payment_id)',  'KDVN Error: Please check, Cannot duplicate Payment !')]
    _defaults = {
                 'date':lambda *a:time.strftime('%Y-%m-%d'),
                 'amount':_new_payment,
                 'currency_id':_get_default_currency,
                 'payment_currency_id':_get_default_currency,
                 'rate':lambda *a:1.0,
                 'actual_amount':_new_payment,
                 }
  
    
kdvn_payment()